package com.blackbird.jang.model;

import java.util.ArrayList;
import java.util.List;

import com.blackbird.jang.Globals;
import com.blackbird.jang.MainActivity;
import com.wiyun.engine.actions.MoveTo;
import com.wiyun.engine.astar.AStar;
import com.wiyun.engine.astar.AStarStep;
import com.wiyun.engine.astar.RectAStarMap;
import com.wiyun.engine.nodes.Layer;
import com.wiyun.engine.nodes.Node;
import com.wiyun.engine.utils.ResolutionIndependent;

/**
 * 
 * 游戏地图
 * 
 * @author jang
 * 
 */
public class GameMap extends RectAStarMap {

	public static float BORDER_UPPER;
	public static float BORDER_BOTTOM;
	public static float BORDER_LEFT;
	public static float BORDER_RIGHT;

	private static Node view;
	private static GameMap instance;

	private static GameModel model;

	public static GameMap make(Layer parent) {
		if (instance == null) {
			initBorder();

			instance = new GameMap(Globals.MAP_COLS, Globals.MAP_ROWS, false);
			model = GameModel.make();
			view = parent;		
		}
		return instance;
	}

	private static void initBorder() {
		BORDER_UPPER = ResolutionIndependent
				.resolveDp(Globals.BORDER_UPPER) * MainActivity.SCALE_Y;

		BORDER_BOTTOM = ResolutionIndependent
				.resolveDp(Globals.BORDER_BOTTOM) * MainActivity.SCALE_Y;

		BORDER_LEFT = ResolutionIndependent.resolveDp(Globals.BORDER_LEFT)
				* MainActivity.SCALE_X;
		BORDER_RIGHT = ResolutionIndependent
				.resolveDp(Globals.BORDER_RIGHT) * MainActivity.SCALE_X;
		
		System.out.println("地图边尺寸：(" + BORDER_UPPER + "," + BORDER_RIGHT
				+ "," + BORDER_BOTTOM + "," + BORDER_LEFT + ")");
	}

	protected GameMap(int width, int height, boolean isAllowDiagonal) {
		super(width, height, isAllowDiagonal);
	}

	// 找出两点间的路径，是否最近？待确认
	public ArrayList<AStarStep> findPath(float x1, float y1, float x2, float y2) {

		int[] xy1 = convertToPositionInt(x1, y1);
		int[] xy2 = convertToPositionInt(x2, y2);

		return AStar.make(this).findPath(xy1[0], xy1[1], xy2[0], xy2[1], false);
	}

	public MoveTo findMoveTo(Block block, AStarStep step) {
		float[] xy = convertToPositionFloat(step.getX(), step.getY());

		return (MoveTo) MoveTo.make(Globals.MOVE_DURATION,
				block.getPositionX(), block.getPositionY(), xy[0], xy[1])
				.autoRelease();
	}

	/**
	 * 查找指定位置附近的所有同类方块
	 */
	public List<Block> findNearBy(float x, float y) {
		int[] xy = convertToPositionInt(x, y);
		return model.findNearBy(xy[0], xy[1]);
	}

	/**
	 * 放置方块
	 */
	public void setBlock(float x, float y, Block o) {
		int[] xy = convertToPositionInt(x, y);

		setBlock(xy[0], xy[1], o);
	}

	public void setBlock(int x, int y, Block s) {
		if (model.getBlock(x, y) == null && !this.isBlockedAt(x, y)) {
			float[] xy = convertToPositionFloat(x, y);
			s.setPosition(xy[0], xy[1]);

			s.setPositionInt(x, y);

			view.addChild(s);

			this.blockTile(x, y);
			model.setBlock(x, y, s);
		}
	}

	/**
	 * 清除方块
	 */
	public void removeBlock(Block block) {
		removeBlock(block.getPositionIntX(), block.getPositionIntY());
	}

	public void removeBlock(float x, float y) {
		int[] xy = convertToPositionInt(x, y);

		removeBlock(xy[0], xy[1]);
	}

	public void removeBlock(int x, int y) {
		if (model.getBlock(x, y) != null && this.isBlockedAt(x, y)) {
			this.freeTile(x, y);
			model.removeBlock(x, y);
			view.removeChild(model.getBlock(x, y), true);			
		}
	}

	public Block getBlock(float x, float y) {
		int[] xy = convertToPositionInt(x, y);

		return getBlock(xy[0], xy[1]);
	}

	public Block getBlock(int x, int y) {
		return model.getBlock(x, y);
	}

	public boolean isFull() {
		return model.isFull();
	}

	/**
	 * 判断是否击中棋盘
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public static boolean isInner(float x, float y) {
		if (x < BORDER_LEFT || x > BORDER_RIGHT) {
			return false;
		}

		if (y < BORDER_BOTTOM || y > BORDER_UPPER) {
			return false;
		}

		return true;
	}

	/**
	 * 把坐标轴的坐标转换成棋盘坐标
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public static int[] convertToPositionInt(float x, float y) {

		int[] r = new int[2];
		r[0] = (int) ((x - BORDER_LEFT) / Block.WIDTH);
		r[1] = (int) ((y - BORDER_BOTTOM) / Block.HEIGHT);

		return r;
	}

	/**
	 * 把棋盘坐标转换成坐标轴的坐标
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public static float[] convertToPositionFloat(int x, int y) {

		float[] r = new float[2];

		r[0] = BORDER_LEFT + x * Block.WIDTH + Block.WIDTH / 2;
		r[1] = BORDER_BOTTOM + y * Block.HEIGHT + Block.HEIGHT / 2;
		return r;
	}
}
